
#include <LengthUnit.h>
#include <Formatter.h>
#include <algorithm>
#include <ostream>

#define BASE_UNIT         FEET
#define FEET_TO_BASE_UNIT 1
#define YARD_TO_BASE_UNIT (3*FEET_TO_BASE_UNIT)
#define MILE_TO_BASE_UNIT (1760*YARD_TO_BASE_UNIT)

#define FEET_NAME "FEET"
#define YARD_NAME "YARD"
#define MILE_NAME "MILE"

namespace{
bool greaterThan(const Unit * lhs, const Unit * rhs)
{
	return *lhs > *rhs;
}
}


const LengthUnit& LengthUnit::getMile()
{
    static const LengthUnit mile(MILE_TO_BASE_UNIT, MILE_NAME, E_LENGTH_TYPE);
    return mile;
}

const LengthUnit& LengthUnit::getYard()
{
    static const LengthUnit yard(YARD_TO_BASE_UNIT, YARD_NAME, E_LENGTH_TYPE);
    return yard;
}

const LengthUnit& LengthUnit::getFeet()
{
    static const LengthUnit feet(FEET_TO_BASE_UNIT, FEET_NAME, E_LENGTH_TYPE);
    return feet;
}

LengthUnit::LengthUnit(int factor, string name, const eUnitType unitType)
	:Unit(factor, name, unitType)
{
}

const Unit& LengthUnit::getBaseUnit() const
{
	return BASE_UNIT;
}


void LengthUnit::appendAndSortUnit(OrderedUnits & orderedunits, const Unit & unit) const
{
	orderedunits.push_back(&unit);
	std::sort(orderedunits.begin(), orderedunits.end(), greaterThan);
}


void LengthUnit::printOrderedUnitsList(const Formatter& formatter)const
{
	OrderedUnits orderedUnits;
	appendAndSortUnit(orderedUnits, YARD);
	appendAndSortUnit(orderedUnits, MILE);
	appendAndSortUnit(orderedUnits, FEET);
	
	for_each(orderedUnits.begin(), orderedUnits.end(), formatter);
}

